
#include<iostream>
using namespace std;

void func1(int&& ii)
{
	cout << "参数是右值 = " << ii << endl;
}

void func1(int& ii)	//重载
{
	cout << "参数是左值 = " << ii << endl;
}

void func2(int& ii)
{
	func1(ii);
}

void func2(int&& ii)
{
	func1(move(ii));
}
int main()
{
	int a = 10;
	func1(a);	//参数是左值 = 10
	func1(8);	//参数是右值 = 8

	//若想实现有中转函数传参左右值区分，如func2中调用func1
	//可以创建两个重载函数func2，参数分别为左值和右值，
	//但值传递仍然是左值，再用move()函数处理右值，这个方法太麻烦了
	func2(a);	//参数是左值 = 10
	func2(8);	//参数是右值 = 8
	return 0;
}







//完美转发
//在函数模板中可以将参数完美的转发给其他函数。
//所谓完美，即不仅能准确的转发参数的值，还能保证被转发参数的左、右值属性不变

//实现完美转发:
//(1)模板中(包括类模板和函数模板)函数参数书写成T&&， 函数左右值引用就都可以接受	
//(2)提供了模板函数std::forward<T>(参数),用于转发参数，转发前后参数左右值属性不变



#include<iostream>
using namespace std;

void func1(int&& ii)
{
	cout << "参数是右值 = " << ii << endl;
}

void func1(int& ii)	//重载
{
	cout << "参数是左值 = " << ii << endl;
}

template<typename T>
void func(T&& ii)
{
	func1(forward<T>(ii));
}
int main()
{
	int a = 10;
	func1(a);	//参数是左值 = 10
	func1(8);	//参数是右值 = 8

	
	func(a);	//参数是左值 = 10
	func(8);	//参数是右值 = 8
	return 0;
}


//注意，形参int&& x这样写只能接受右值，只有模板通用参数定义T&& x才能都接受